//
// Created by 伍泉 on 2024/6/7.
//

#include "FFmpegCoder.h"
#include <jni.h>

// 全局的 FFmpegCodec 实例
static FFmpegCodec* ffmpegCodec = new FFmpegCodec();

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_helloffmpeg_system_FfmpegHelper_convertAudioToAAC(JNIEnv *env, jobject thiz,
                                                                   jstring inputFilePath, jstring outputFilePath) {
    const char *input = env->GetStringUTFChars(inputFilePath, 0);
    const char *output = env->GetStringUTFChars(outputFilePath, 0);

    bool result = ffmpegCodec->convertAudioToAAC(input, output);

    env->ReleaseStringUTFChars(inputFilePath, input);
    env->ReleaseStringUTFChars(outputFilePath, output);

    return result ? JNI_TRUE : JNI_FALSE;
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_helloffmpeg_system_FfmpegHelper_convertVideoToH264(JNIEnv *env, jobject thiz,
                                                                    jstring inputFilePath, jstring outputFilePath) {
    const char *input = env->GetStringUTFChars(inputFilePath, 0);
    const char *output = env->GetStringUTFChars(outputFilePath, 0);

    bool result = ffmpegCodec->convertVideoToH264(input, output);

    env->ReleaseStringUTFChars(inputFilePath, input);
    env->ReleaseStringUTFChars(outputFilePath, output);

    return result ? JNI_TRUE : JNI_FALSE;
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_helloffmpeg_system_FfmpegHelper_decode(JNIEnv *env, jobject thiz,
                                                        jstring inputFilePath,
                                                        jstring videoOutputFilePath,
                                                        jstring audioOutputFilePath) {
    const char *input = env->GetStringUTFChars(inputFilePath, 0);
    const char *videoOutput = env->GetStringUTFChars(videoOutputFilePath, 0);
    const char *audioOutput = env->GetStringUTFChars(audioOutputFilePath, 0);

    bool result = ffmpegCodec->decode(input, videoOutput, audioOutput);

    env->ReleaseStringUTFChars(inputFilePath, input);
    env->ReleaseStringUTFChars(videoOutputFilePath, videoOutput);
    env->ReleaseStringUTFChars(audioOutputFilePath, audioOutput);

    return result ? JNI_TRUE : JNI_FALSE;

}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_example_helloffmpeg_system_FfmpegHelper_encode(JNIEnv *env, jobject thiz,
                                                        jstring videoInputFilePath,
                                                        jstring audioInputFilePath,
                                                        jstring outputFilePath) {
    const char *videoInput = env->GetStringUTFChars(videoInputFilePath, 0);
    const char *audioInput = env->GetStringUTFChars(audioInputFilePath, 0);
    const char *output = env->GetStringUTFChars(outputFilePath, 0);

    bool result = ffmpegCodec->encode(videoInput, audioInput, output);

    env->ReleaseStringUTFChars(videoInputFilePath, videoInput);
    env->ReleaseStringUTFChars(audioInputFilePath, audioInput);
    env->ReleaseStringUTFChars(outputFilePath, output);

    return result ? JNI_TRUE : JNI_FALSE;
}

bool FFmpegCodec::encode(const char* videoInput, const char* audioInput, const char* output) {
    return ffmpegWrapper->encode(videoInput, audioInput, output);
}

FFmpegCodec::FFmpegCodec() {
    ffmpegWrapper = new FFmpegWrapper();
    ffmpegWrapper-> initFFmpeg();
}

FFmpegCodec::~FFmpegCodec() {
    if(ffmpegWrapper){
        ffmpegWrapper->cleanup();
        delete ffmpegWrapper;
    }
}

bool FFmpegCodec::decode(const char *inputFilename, const char *videoOutputFilename,
                         const char *audioOutputFilename) {
    return ffmpegWrapper->decode(inputFilename, videoOutputFilename, audioOutputFilename);
}

bool FFmpegCodec::convertAudioToAAC(const char *inputFilename, const char *outputFilename) {
    return ffmpegWrapper->convertAudioToAAC(inputFilename, outputFilename);
}

bool FFmpegCodec::convertVideoToH264(const char *inputFilename, const char *outputFilename) {
    return ffmpegWrapper->convertVideoToH264(inputFilename,outputFilename);
}

void FFmpegCodec::decodeVideo(AVCodecContext *avCodecContext, AVFrame *avFrame, AVPacket *pkt, const char *filename) {
    ffmpegWrapper ->decodeVideo(avCodecContext,avFrame,pkt,filename);
}

void FFmpegCodec::decodeAudio(AVCodecContext *avCodecContext, AVPacket *pkt, AVFrame *avFrame,
                              FILE *outfile) {
    ffmpegWrapper ->decodeAudio(avCodecContext,pkt,avFrame,outfile);
}

void FFmpegCodec::saveYUV(AVFrame *avFrame, char *filename) {
    ffmpegWrapper ->saveYUV(avFrame,filename);
}

int FFmpegCodec::getSampleFmtFromName(const char **fmt, enum AVSampleFormat sample_fmt) {
    ffmpegWrapper ->getSampleFmtFromName(fmt,sample_fmt);
}
